package com.cxs.plan.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.cxs.plan.VO.*;
import com.cxs.plan.annotation.PagingQuery;
import com.cxs.plan.constant.MonthEnum;
import com.cxs.plan.domain.entity.PayCard;
import com.cxs.plan.domain.entity.PayType;
import com.cxs.plan.domain.entity.PayVariation;
import com.cxs.plan.mapper.*;
import com.cxs.plan.service.PayVariationService;
import com.cxs.plan.utils.BaseContext;
import com.cxs.plan.utils.FormatterUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.time.LocalDate;
import java.util.List;
import java.util.concurrent.atomic.AtomicReference;
import java.util.stream.Collectors;

/**
* @author Administrator
* @description 针对表【pay_variation(消费/收入记录)】的数据库操作Service实现
* @createDate 2024-04-02 15:59:43
*/
@Service
public class PayVariationServiceImpl extends ServiceImpl<PayVariationMapper, PayVariation>
    implements PayVariationService{


    @Autowired
    private BillMapper billMapper;

    @Autowired
    private PayTypeMapper payTypeMapper;

    @Autowired
    private PayCardMapper payCardMapper;

    @Autowired
    private PayVariationMapper payVariationMapper;

    @Autowired
    private BudgetMapper budgetMapper;

    @Override
    public JSONObject getUserPayType() {
        BaseContext.getCurrentId();
        List<PayType> income = payTypeMapper.selectPayTypeList(1, 1);  // 收入
        List<PayType> expend = payTypeMapper.selectPayTypeList(0, 1);  // 支出

        JSONObject obj = new JSONObject();
        obj.put("income", income);
        obj.put("expend", expend);
        return obj;
    }

    @Override
    public List<PayCard> getUserPayCard() {
        LambdaQueryWrapper<PayCard> wrapper = new LambdaQueryWrapper<>();
        wrapper.select(PayCard::getId, PayCard::getName).eq(PayCard::getUserId, BaseContext.getCurrentId());
        return payCardMapper.selectList(wrapper);
    }

    @Transactional
    @Override
    public void savePayVariation(PayVariation payVariation) {
        // 账户余额
        BigDecimal balance = payCardMapper.selectBalanceByCardId(payVariation.getCardId());
        if (payVariation.getType() == 0) {
            balance = balance.subtract(payVariation.getPrice());
            payVariation.setPrice(payVariation.getPrice().negate());
        } else {
            balance = balance.add(payVariation.getPrice());
        }
        payVariation.setBalance(balance);
        if(balance.compareTo(BigDecimal.ZERO) < 0) {
            throw new RuntimeException("余额不足");
        }
        // 更新账户余额
        payCardMapper.updateMoneyByCardId(payVariation.getCardId(), balance);
        payVariationMapper.insert(payVariation);
    }

    @Override
    @PagingQuery
    public List<VariationVO> getPayVariationList(Integer billId) {
        Integer currentId = BaseContext.getCurrentId();
        return payVariationMapper.selectVariationList(currentId, billId);
    }

    @Override
    public List<BillVO> getBillList() {
        Integer currentId = BaseContext.getCurrentId();
        return billMapper.selectBillByUserId(currentId);
    }

    @Override
    public List<PayVO> getPayVariationByDate(String date) {
        LocalDate localDate = LocalDate.parse(date);
        int month = localDate.getMonthValue();
        String monthKey = MonthEnum.getMonthKey(month);
        // 获取月预算
        Integer budget = budgetMapper.selectMonthBudget(BaseContext.getCurrentId(), localDate.getYear(), monthKey);
        // 获取当月消费记录
        List<PayVO> payVOList = payVariationMapper.selectByDate(date, BaseContext.getCurrentId(), monthKey);
        // 使用 AtomicReference 包装 budgetPrice
        AtomicReference<BigDecimal> budgetPriceRef = new AtomicReference<>(new BigDecimal(budget));
        // 计算剩余预算
        payVOList = payVOList.stream().map(payVO -> {
            BigDecimal price = new BigDecimal(payVO.getPrice());
            if(price.compareTo(BigDecimal.ZERO) < 0) {
                budgetPriceRef.set(budgetPriceRef.get().add(price)); // 修改 budgetPrice
            }
            BigDecimal surplus = budgetPriceRef.get(); // 计算 surplus
            if(surplus.compareTo(BigDecimal.ZERO) < 0) {
                payVO.setSurplusRate(0);
                payVO.setSurplus(FormatterUtil.formatAmount(surplus.toString()));
                return  payVO;
            }
            // 计算剩余预算比例
            BigDecimal surplusRateDecimal = surplus.divide(new BigDecimal(budget), 4, BigDecimal.ROUND_HALF_UP);
            // 将剩余预算比例转换为百分比
            double surplusRatePercentage = surplusRateDecimal.multiply(new BigDecimal(100)).doubleValue();
            payVO.setSurplusRate(surplusRatePercentage);
            payVO.setSurplus(FormatterUtil.formatAmount(surplus.toString()));
            return payVO;
        }).collect(Collectors.toList());
        return payVOList;
    }

    @Override
    public JSONObject getPayVariationMonthByDate(String date) {
        JSONObject object = new JSONObject();
        List<DayPayBriefVO> payList = payVariationMapper.selectEveryDaySumByDate(date, BaseContext.getCurrentId());
        MonthPayBriefVO monthPayBriefVO = payVariationMapper.selectMonthSumByDate(date, BaseContext.getCurrentId());
        object.put("payList", payList);
        object.put("income", monthPayBriefVO.getIncome());
        object.put("expend", monthPayBriefVO.getExpend());
        return object;
    }
}




